<!-- HTML header for doxygen 1.8.3.1-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.3.1"/>
<title>AngelScript: Registering a function</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<script type="test/javascript" src="touch.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript">
  $(document).ready(initResizable);
  $(window).load(resizeHeight);
</script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/search.js"></script>
<script type="text/javascript">
  $(document).ready(function() { searchBox.OnSelectItem(0); });
</script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  <td id="projectlogo"><img alt="Logo" src="aslogo_small.png"/></td>
  <td style="padding-left: 0.5em;">
   <div id="projectname">AngelScript
   </div>
  </td>
   <td>        <div id="MSearchBox" class="MSearchBoxInactive">
        <span class="left">
          <img id="MSearchSelect" src="search/mag_sel.png"
               onmouseover="return searchBox.OnSearchSelectShow()"
               onmouseout="return searchBox.OnSearchSelectHide()"
               alt=""/>
          <input type="text" id="MSearchField" value="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)" 
               onblur="searchBox.OnSearchFieldFocus(false)" 
               onkeyup="searchBox.OnSearchFieldChange(event)"/>
          </span><span class="right">
            <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
          </span>
        </div>
</td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.3.1 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "search",false,'Search');
</script>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
  <div id="nav-tree">
    <div id="nav-tree-contents">
      <div id="nav-sync" class="sync"></div>
    </div>
  </div>
  <div id="splitbar" style="-moz-user-select:none;" 
       class="ui-resizable-handle">
  </div>
</div>
<script type="text/javascript">
$(document).ready(function(){initNavTree('doc_register_func.html','');});
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark">&#160;</span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark">&#160;</span>Classes</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark">&#160;</span>Files</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark">&#160;</span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark">&#160;</span>Variables</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(5)"><span class="SelectionMark">&#160;</span>Typedefs</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(6)"><span class="SelectionMark">&#160;</span>Enumerations</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(7)"><span class="SelectionMark">&#160;</span>Enumerator</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(8)"><span class="SelectionMark">&#160;</span>Macros</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(9)"><span class="SelectionMark">&#160;</span>Pages</a></div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div class="header">
  <div class="headertitle">
<div class="title">Registering a function </div>  </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p>This article aims to explain the way functions are registered with AngelScript, and some of the differences between C++ and AngelScript that the developer needs to be aware of in order to be successful in registering the application interface that the scripts will use. The principles learned here are used in several locations, such as <a class="el" href="classas_i_script_engine.html#a2f84b9b51733f22c68b8448b02c2f1c7">RegisterGlobalFunction</a>, <a class="el" href="classas_i_script_engine.html#a1d42c5d9fd06a07da279f491f8901317">RegisterObjectMethod</a>, <a class="el" href="classas_i_script_engine.html#ad69bc821a7f1120369c1bd9526f41b9c">RegisterObjectBehaviour</a>, etc.</p>
<h1><a class="anchor" id="doc_register_func_1"></a>
How to get the address of the application function or method</h1>
<p>The macros <a class="el" href="angelscript_8h.html#a78f8f2c7f1c88b12e74a5ac47b4184ae">asFUNCTION</a>, <a class="el" href="angelscript_8h.html#a153aee5a6228913a469b6e6867e54efb">asFUNCTIONPR</a>, <a class="el" href="angelscript_8h.html#a7345e6b3afabec24efd0ff77886d49a6">asMETHOD</a>, and <a class="el" href="angelscript_8h.html#ac45ccb5854326cce38d721e2c00f1563">asMETHODPR</a> have been implemented to facilitate the task of getting the function pointer and passing them on to the script engine.</p>
<p>The asFUNCTION takes the function name as the parameter, which works for all global functions that do not have any overloads. If you use overloads, i.e. multiple functions with the same name but with different parameters, then you need to use asFUNCTIONPR instead. This macro takes as parameter the function name, parameter list, and return type, so that the C++ compiler can resolve exactly which overloaded function to take the address of.</p>
<div class="fragment"><div class="line"><span class="comment">// Global function</span></div>
<div class="line"><span class="keywordtype">void</span> globalFunc();</div>
<div class="line">r = engine-&gt;<a class="code" href="classas_i_script_engine.html#a2f84b9b51733f22c68b8448b02c2f1c7" title="Registers a global function.">RegisterGlobalFunction</a>(<span class="stringliteral">&quot;void globalFunc()&quot;</span>, <a class="code" href="angelscript_8h.html#a78f8f2c7f1c88b12e74a5ac47b4184ae" title="Returns an asSFuncPtr representing the function specified by the name.">asFUNCTION</a>(globalFunc), <a class="code" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4a68ae43cc91cdfc3fa4590c9e6164e4f4" title="A cdecl function.">asCALL_CDECL</a>); assert( r &gt;= 0 );</div>
<div class="line"></div>
<div class="line"><span class="comment">// Overloaded global functions</span></div>
<div class="line"><span class="keywordtype">void</span> globalFunc2(<span class="keywordtype">int</span>);</div>
<div class="line"><span class="keywordtype">void</span> globalFunc2(<span class="keywordtype">float</span>);</div>
<div class="line">r = engine-&gt;<a class="code" href="classas_i_script_engine.html#a2f84b9b51733f22c68b8448b02c2f1c7" title="Registers a global function.">RegisterGlobalFunction</a>(<span class="stringliteral">&quot;void globalFunc2(int)&quot;</span>, <a class="code" href="angelscript_8h.html#a153aee5a6228913a469b6e6867e54efb" title="Returns an asSFuncPtr representing the function specified by the name, parameter list, and return type.">asFUNCTIONPR</a>(globalFunc2, (<span class="keywordtype">int</span>), <span class="keywordtype">void</span>), <a class="code" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4a68ae43cc91cdfc3fa4590c9e6164e4f4" title="A cdecl function.">asCALL_CDECL</a>); assert( r &gt;= 0 );</div>
</div><!-- fragment --><p>The same goes for asMETHOD and asMETHODPR. The difference between these and asFUNCTION/asFUNCTIONPR is that the former take the class name as well as parameter.</p>
<div class="fragment"><div class="line"><span class="keyword">class </span>Object</div>
<div class="line">{</div>
<div class="line">  <span class="comment">// Class method</span></div>
<div class="line">  <span class="keywordtype">void</span> method();</div>
<div class="line">  </div>
<div class="line">  <span class="comment">// Overloaded method</span></div>
<div class="line">  <span class="keywordtype">void</span> method2(<span class="keywordtype">int</span> input);</div>
<div class="line">  <span class="keywordtype">void</span> method2(<span class="keywordtype">int</span> input, <span class="keywordtype">int</span> &amp;output);</div>
<div class="line">  </div>
<div class="line">  <span class="comment">// Const method</span></div>
<div class="line">  <span class="keywordtype">int</span> getAttr(<span class="keywordtype">int</span>) <span class="keyword">const</span>;</div>
<div class="line">};</div>
<div class="line"></div>
<div class="line"><span class="comment">// Registering the class method</span></div>
<div class="line">r = engine-&gt;<a class="code" href="classas_i_script_engine.html#a1d42c5d9fd06a07da279f491f8901317" title="Registers a method for the object type.">RegisterObjectMethod</a>(<span class="stringliteral">&quot;object&quot;</span>, <span class="stringliteral">&quot;void method()&quot;</span>, <a class="code" href="angelscript_8h.html#a7345e6b3afabec24efd0ff77886d49a6" title="Returns an asSFuncPtr representing the class method specified by class and method name...">asMETHOD</a>(Object,method), <a class="code" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4aea516c8742acc1edff6a43dc1bb09e96" title="A thiscall class method.">asCALL_THISCALL</a>); assert( r &gt;= 0 );</div>
<div class="line"></div>
<div class="line"><span class="comment">// Registering the overloaded methods</span></div>
<div class="line">r = engine-&gt;<a class="code" href="classas_i_script_engine.html#a1d42c5d9fd06a07da279f491f8901317" title="Registers a method for the object type.">RegisterObjectMethod</a>(<span class="stringliteral">&quot;object&quot;</span>, <span class="stringliteral">&quot;void method2(int)&quot;</span>, <a class="code" href="angelscript_8h.html#ac45ccb5854326cce38d721e2c00f1563" title="Returns an asSFuncPtr representing the class method specified by class, method name, parameter list, return type.">asMETHODPR</a>(Object, method2, (<span class="keywordtype">int</span>), <span class="keywordtype">void</span>), <a class="code" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4aea516c8742acc1edff6a43dc1bb09e96" title="A thiscall class method.">asCALL_THISCALL</a>); assert( r &gt;= 0 );</div>
<div class="line">r = engine-&gt;<a class="code" href="classas_i_script_engine.html#a1d42c5d9fd06a07da279f491f8901317" title="Registers a method for the object type.">RegisterObjectMethod</a>(<span class="stringliteral">&quot;object&quot;</span>, <span class="stringliteral">&quot;void method2(int, int &amp;out)&quot;</span>, <a class="code" href="angelscript_8h.html#ac45ccb5854326cce38d721e2c00f1563" title="Returns an asSFuncPtr representing the class method specified by class, method name, parameter list, return type.">asMETHODPR</a>(Object, method2, (<span class="keywordtype">int</span>, <span class="keywordtype">int</span>&amp;), <span class="keywordtype">void</span>), <a class="code" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4aea516c8742acc1edff6a43dc1bb09e96" title="A thiscall class method.">asCALL_THISCALL</a>); assert( r &gt;= 0 );</div>
<div class="line"></div>
<div class="line"><span class="comment">// Registering a const method</span></div>
<div class="line">r = engine-&gt;<a class="code" href="classas_i_script_engine.html#a1d42c5d9fd06a07da279f491f8901317" title="Registers a method for the object type.">RegisterObjectMethod</a>(<span class="stringliteral">&quot;object&quot;</span>, <span class="stringliteral">&quot;int getAttr(int) const&quot;</span>, <a class="code" href="angelscript_8h.html#ac45ccb5854326cce38d721e2c00f1563" title="Returns an asSFuncPtr representing the class method specified by class, method name, parameter list, return type.">asMETHODPR</a>(Object, getAttr, (<span class="keywordtype">int</span>) <span class="keyword">const</span>, <span class="keywordtype">int</span>), <a class="code" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4aea516c8742acc1edff6a43dc1bb09e96" title="A thiscall class method.">asCALL_THISCALL</a>); assert( r &gt;= 0 );</div>
</div><!-- fragment --><p>It is possible to register a class method to be called from the script as if it was a global function. This is commonly done when exposing a singleton to the script interface, as the singleton's methods then look like ordinary global functions. When this is done the application must have a reference to the object at the time of the registration and the application must guarantee that the object is alive until it is no longer possible for the scripts to call the method.</p>
<div class="fragment"><div class="line"><span class="keyword">class </span>MySingleton</div>
<div class="line">{</div>
<div class="line">  <span class="comment">// Class method to be called from script as if a global function</span></div>
<div class="line">  <span class="keywordtype">void</span> MyGlobalFunc(<span class="keywordtype">int</span> arg1, <span class="keywordtype">int</span> arg2);</div>
<div class="line">};</div>
<div class="line"></div>
<div class="line">MySingleton single;</div>
<div class="line"></div>
<div class="line"><span class="comment">// Registering the singleton&#39;s method as if a global function</span></div>
<div class="line">r = engine-&gt;<a class="code" href="classas_i_script_engine.html#a2f84b9b51733f22c68b8448b02c2f1c7" title="Registers a global function.">RegisterGlobalFunction</a>(<span class="stringliteral">&quot;void MyGlobalFunc(int, int)&quot;</span>, <a class="code" href="angelscript_8h.html#a7345e6b3afabec24efd0ff77886d49a6" title="Returns an asSFuncPtr representing the class method specified by class and method name...">asMETHOD</a>(MySingleton, MyGlobalFunc), <a class="code" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4aa241a0c1deedaa2d55eb99a83829efad" title="A thiscall class method registered as a global function.">asCALL_THISCALL_ASGLOBAL</a>, &amp;single); assert( r &gt;= 0 );</div>
</div><!-- fragment --><h1><a class="anchor" id="doc_register_func_2"></a>
Calling convention</h1>
<p>AngelScript accepts most common calling conventions that C++ uses, i.e. cdecl, stdcall, and thiscall. There is also a generic calling convention that can be used for example when native calling conventions are not supported on the target platform.</p>
<p>All functions and behaviours must be registered with the <a class="el" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4a68ae43cc91cdfc3fa4590c9e6164e4f4">asCALL_CDECL</a>, <a class="el" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4a138a08e8363ebc695636dfe987674e2e">asCALL_STDCALL</a>, <a class="el" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4aea516c8742acc1edff6a43dc1bb09e96">asCALL_THISCALL</a>, or <a class="el" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4a750c26b6a6e0c9ccbb93078f532ef8ce">asCALL_GENERIC</a> flags to tell AngelScript which calling convention the application function uses. The special conventions <a class="el" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4ac08652c72f1cc0dc81c37812fab0e253">asCALL_CDECL_OBJLAST</a> and <a class="el" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4a7c3e88628c2722d0a103b411d4aceaa0">asCALL_CDECL_OBJFIRST</a> can also be used wherever asCALL_THISCALL is accepted, in order to simulate a class method through a global function. Functor objects can also be used to emulate global functions with the convention <a class="el" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4aa241a0c1deedaa2d55eb99a83829efad">asCALL_THISCALL_ASGLOBAL</a>, or class methods with the conventions <a class="el" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4a613a388ed51315f6fce19f3824d6b17a">asCALL_THISCALL_OBJFIRST</a> and <a class="el" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4a491f0ab2b66032a7b5541364f7f225b1">asCALL_THISCALL_OBJLAST</a>.</p>
<p>If the incorrect calling convention is given on the registration you'll very likely see the application crash with a stack corruption whenever the script engine calls the function. cdecl is the default calling convention for all global functions in C++ programs, so if in doubt try with asCALL_CDECL first. The calling convention only differs from cdecl if the function is explicitly declared to use a different convention, or if you've set the compiler options to default to another convention.</p>
<p>For class methods there is only the thiscall convention, except when the method is static, as those methods are in truth global functions in the class namespace. Normal methods, virtual methods, and methods for classes with multiple inheritance are all registered the same way, with asCALL_THISCALL.</p>
<p>Classes with <a class="el" href="doc_register_func.html#doc_register_func_4">virtual inheritance are not supported natively</a>, and for these it will be necessary to create wrapper functions. These wrapper functions can either be implemented manually, or the template based automatic wrappers from the <a class="el" href="doc_addon_autowrap.html">add-on</a> can be used.</p>
<dl class="section see"><dt>See Also</dt><dd><a class="el" href="doc_generic.html">The generic calling convention</a></dd></dl>
<h1><a class="anchor" id="doc_register_func_3"></a>
A little on type differences</h1>
<p>AngelScript supports most of the same types that C++ has, but there are differences that you'll need to know when registering functions, methods, and behaviours. Make sure you read and understand the article <a class="el" href="doc_as_vs_cpp_types.html">Datatypes in AngelScript and C++</a>.</p>
<p>When registering functions that take references, you must make sure to inform the correct keyword that informs the intention of the data in the reference. For example, a parameter reference that is meant to be used as input should have the keyword 'in' defined after the &amp; character, and an output reference should have the keyword 'out'. <a class="el" href="doc_reg_basicref.html">Reference types</a> can be passed as both input and output references, in which case the keyword 'inout' can be used, or simply no keyword at all. <a class="el" href="doc_register_val_type.html">Value types</a> on the other hand cannot use 'inout' references, as AngelScript cannot guarantee that the reference will be valid during the whole execution of the function.</p>
<p>When registering functions that take pointers, you need to determine what the pointer represents. If the pointer is to a value type though, then it can only be registered as a reference. If the pointer is to a reference type, then it can be registered as an <a class="el" href="doc_obj_handle.html">object handle</a>, or as a plain reference. If you choose to use the object handle then you need to pay attention to the reference counter in the type so you don't get problems with memory leaks or crashes due to objects being destroyed too early.</p>
<h1><a class="anchor" id="doc_register_func_4"></a>
Virtual inheritance is not supported</h1>
<p>Registering class methods for classes with virtual inheritance is not supported due to the high complexity involved with them. Each compiler implements the method pointers for these classes differently, and keeping the code portable would be very difficult. This is not a great loss though, as classes with virtual inheritance are relatively rare, and it is easy to write simple proxy functions where the classes to exist.</p>
<div class="fragment"><div class="line"><span class="keyword">class </span>A { <span class="keywordtype">void</span> SomeMethodA(); };</div>
<div class="line"><span class="keyword">class </span>B : <span class="keyword">virtual</span> A {};</div>
<div class="line"><span class="keyword">class </span>C : <span class="keyword">virtual</span> A {};</div>
<div class="line"><span class="keyword">class </span>D : <span class="keyword">public</span> B, <span class="keyword">public</span> C {};</div>
<div class="line"></div>
<div class="line"><span class="comment">// Need a proxy function for registering SomeMethodA for class D</span></div>
<div class="line"><span class="keywordtype">void</span> D_SomeMethodA_proxy(D *d)</div>
<div class="line">{</div>
<div class="line">  <span class="comment">// The C++ compiler will resolve the virtual method for us</span></div>
<div class="line">  d-&gt;SomeMethodA();</div>
<div class="line">}</div>
<div class="line"></div>
<div class="line"><span class="comment">// Register the global function as if it was a class method, </span></div>
<div class="line"><span class="comment">// but with calling convention asCALL_CDECL_OBJLAST</span></div>
<div class="line">engine-&gt;<a class="code" href="classas_i_script_engine.html#a1d42c5d9fd06a07da279f491f8901317" title="Registers a method for the object type.">RegisterObjectMethod</a>(<span class="stringliteral">&quot;D&quot;</span>, <span class="stringliteral">&quot;void SomeMethodA()&quot;</span>, <a class="code" href="angelscript_8h.html#a78f8f2c7f1c88b12e74a5ac47b4184ae" title="Returns an asSFuncPtr representing the function specified by the name.">asFUNCTION</a>(D_SomeMethodA_proxy), <a class="code" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4ac08652c72f1cc0dc81c37812fab0e253" title="A cdecl function that takes the object pointer as the last parameter.">asCALL_CDECL_OBJLAST</a>);</div>
</div><!-- fragment --><p>If you have a lot of classes with virtual inheritance, you should probably think about writing a template proxy function, so you don't have to manually write all the proxy functions. </p>
</div></div><!-- contents -->
</div><!-- doc-content -->
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
  <ul>
    <li class="footer">Generated on Sun Dec 18 2016 12:35:29 for AngelScript by
    <a href="http://www.doxygen.org/index.html">
    <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.3.1 </li>
  </ul>
</div>
</body>
</html>
